package com.dfiov.cloud.msmtools.service.business.impl;

import com.alibaba.fastjson.JSON;
import com.dfiov.cloud.msmtools.contant.msbluetooth.BluetoothKeyStatusEnum;
import com.dfiov.cloud.msmtools.contant.msbluetooth.BluetoothKeyTypeEnum;
import com.dfiov.cloud.msmtools.contant.msdevice.RealNameStatusEnum;
import com.dfiov.cloud.msmtools.entity.vo.msbluetooth.BluetoothVo;
import com.dfiov.cloud.msmtools.entity.vo.msbluetooth.VinBluetoothsVo;
import com.dfiov.cloud.msmtools.mapper.entity.msaccount.BaseAccountBindDo;
import com.dfiov.cloud.msmtools.mapper.entity.msbluetooth.BluetoothUserKeyDo;
import com.dfiov.cloud.msmtools.mapper.entity.msdevice.BaseDeviceVehicleDo;
import com.dfiov.cloud.msmtools.mapper.entity.msdevice.IngeekBluetoothDataDo;
import com.dfiov.cloud.msmtools.mapper.entity.msrnauth.MsRnauthInfoDo;
import com.dfiov.cloud.msmtools.mapper.entity.msuser.BaseUserInfoDo;
import com.dfiov.cloud.msmtools.mapper.msaccount.MsAccountMapper;
import com.dfiov.cloud.msmtools.mapper.msbluetooth.MsBluetoothMapper;
import com.dfiov.cloud.msmtools.mapper.msdevice.MsDeviceMapper;
import com.dfiov.cloud.msmtools.mapper.msrnauth.MsRnauthMapper;
import com.dfiov.cloud.msmtools.mapper.msuser.MsUserMapper;
import com.dfiov.cloud.msmtools.service.business.MsBluetoothService;
import com.dfiov.cloud.msmtools.utils.DateUtils;
import com.pateo.qingcloud.framework.common.base.BaseRestResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class MsBluetoothServiceImpl implements MsBluetoothService {

    @Autowired
    MsBluetoothMapper msBluetoothMapper;

    @Autowired
    MsRnauthMapper msRnauthMapper;

    @Autowired
    MsDeviceMapper msDeviceMapper;

    @Autowired
    MsAccountMapper msAccountMapper;

    @Autowired
    MsUserMapper msUserMapper;

    @Override
    public BaseRestResponse<VinBluetoothsVo> getBluetoothByVin(String vin) {
        BaseRestResponse<VinBluetoothsVo> response = null;
        VinBluetoothsVo vinBluetoothsVo = null;

        //region 查询车辆信息
        BaseDeviceVehicleDo baseDeviceVehicleDo = getVehicleInfoByVin(vin);
        if(baseDeviceVehicleDo == null) {
            response = new BaseRestResponse<>("-1", "无效VIN");
            return response;
        }
        vinBluetoothsVo = new VinBluetoothsVo()
                .setVin(vin)
                .setBluetooths(new ArrayList<>())
                .setBrandCode(baseDeviceVehicleDo.getBrandCode())
                .setBrandName(baseDeviceVehicleDo.getBrandName())
                .setSeriesCode(baseDeviceVehicleDo.getSeriesCode())
                .setSeriesName(baseDeviceVehicleDo.getSeriesName())
                .setStyleCode(baseDeviceVehicleDo.getStyleCode())
                .setStyleName(baseDeviceVehicleDo.getStyleName())
                .setVhlStatus(baseDeviceVehicleDo.getStatus())
                .setEnrollStatus(baseDeviceVehicleDo.getEnrollStatus())
                .setTboxPdsn(baseDeviceVehicleDo.getTboxPdsn());

        if(StringUtils.isEmpty(baseDeviceVehicleDo.getTboxPdsn())){
            log.warn("车辆:{}未绑定Tbox", vin);
            response = new BaseRestResponse<>("0", "车辆:"+vin+"未绑定Tbox", vinBluetoothsVo);
            return response;
        }
        //endregion

        //region 查询车辆实名认证信息
        MsRnauthInfoDo rnauthInfoDo = getRnauthInfoByVin(vin);
        if(rnauthInfoDo != null) {
            vinBluetoothsVo.setRealNameStatus(RealNameStatusEnum.getInfoByValue(Integer.valueOf(rnauthInfoDo.getRealNameStatus())));
        }
        //endregion

        //region 查询车主信息
        BaseAccountBindDo accountBindDo = getAccountBindDoByTbox(baseDeviceVehicleDo.getTboxPdsn());
        if (accountBindDo != null && !StringUtils.isEmpty(accountBindDo.getUserAccountId())) {
            BaseUserInfoDo baseUserInfoDo = getUserInfoByAccountId(accountBindDo.getUserAccountId());
            if (baseUserInfoDo != null) {
                vinBluetoothsVo.setOwnerAccountId(baseUserInfoDo.getAccountId())
                        .setOwnerUid(baseUserInfoDo.getUid())
                        .setOwnerMobilePhone(baseUserInfoDo.getMobilePhone())
                        .setOwnerThirdType(baseUserInfoDo.getThirdType())
                        .setOwnerThirdUid(baseUserInfoDo.getThirdUid());
            }
        }
        //endregion

        //region 查银基蓝牙
        response = getIneekByVin(vinBluetoothsVo, vin);
        if (response != null) {
            return response;
        }
        //endregion

        //region 查询传统蓝牙钥匙
        response = getPateoByVin(vinBluetoothsVo, vin);
        if (response != null) {
            return response;
        }
        //endregion

        //region 查询自研蓝牙钥匙
        response = getDongfengByVin(vinBluetoothsVo, vin);
        if (response != null) {
            return response;
        }
        //endregion

        return null;
    }

    /* 获取车辆信息 */
    private BaseDeviceVehicleDo getVehicleInfoByVin(String vin) {
        BaseDeviceVehicleDo vehicleInfoDo = null;
        try {
            vehicleInfoDo = msDeviceMapper.getVehicleInfoByVin(vin);
            log.info("根据vin:{}获取车辆信息成功:{}", vin, JSON.toJSONString(vehicleInfoDo));
            return vehicleInfoDo;
        } catch (Exception e) {
            log.error("根据vin:{}获取车辆信息失败:{}", vin, JSON.toJSONString(e));
            return null;
        }
    }

    /* 获取车辆实名认证信息 */
    private MsRnauthInfoDo getRnauthInfoByVin(String vin) {
        MsRnauthInfoDo rnauthInfoDo = null;
        try {
            rnauthInfoDo = msRnauthMapper.getMsRnauthInfoByVin(vin);
            log.info("根据vin:{}获取车辆实名认证信息成功:{}", vin, JSON.toJSONString(rnauthInfoDo));
            return rnauthInfoDo;
        } catch (Exception e) {
            log.error("根据vin:{}获取车辆实名认证信息失败:{}", vin, JSON.toJSONString(e));
            return null;
        }
    }

    /* 获取车主账户编码 */
    private BaseAccountBindDo getAccountBindDoByTbox(String tboxPdsn) {
        if(StringUtils.isEmpty(tboxPdsn)) {
            log.error("根据tboxPdsn:{}获取车主账户编码入参tboxPdsn为空", tboxPdsn);
            return null;
        }

        BaseAccountBindDo accountBindDo = null;

        try {
            accountBindDo = msAccountMapper.findBindAccountByDeviceAccountId(tboxPdsn);
            log.info("根据tboxPdsn:{}获取车主账户编码成功:{}", tboxPdsn, accountBindDo.getUserAccountId());
        } catch (Exception e) {
            log.error("根据tboxPdsn:{}获取车主账户编码失败:{}", tboxPdsn,JSON.toJSONString(e));
            return null;
        }

        if (accountBindDo == null) {
            log.error("根据tboxPdsn:{}获取车主账户编码失败，无车主", tboxPdsn);
            return null;
        }

        if (StringUtils.isEmpty(accountBindDo.getUserAccountId())) {
            log.error("根据tboxPdsn:{}获取车主账户编码失败，车主账户编码为空", tboxPdsn);
            return null;
        }

        return accountBindDo;
    }

    /* 获取用户信息 */
    private BaseUserInfoDo getUserInfoByAccountId(String accountId) {
        if(StringUtils.isEmpty(accountId)) {
            log.error("获取用户信息入参accountId为空");
            return null;
        }

        BaseUserInfoDo baseUserInfoDo = null;
        try {
            baseUserInfoDo = msUserMapper.getUserInfoByAccountId(accountId);
            log.info("根据accountId:{}获取用户信息成功{}", accountId, JSON.toJSONString(baseUserInfoDo));
            return baseUserInfoDo;
        } catch (Exception e) {
            log.error("根据accountId:{}获取用户信息失败:{}", accountId, JSON.toJSONString(e));
            return null;
        }
    }

    /* 获取用户信息 */
    private BaseUserInfoDo getUserInfoByAccountSid(Long userAccountSid) {
        if(userAccountSid == null) {
            log.error("根据userAccountSid:{}获取用户信息入参userAccountSid为空");
            return null;
        }

        BaseUserInfoDo baseUserInfoDo = null;
        try {
            baseUserInfoDo = msUserMapper.getUserInfoByAccountSid(userAccountSid);
            log.info("根据userAccountSid:{}获取用户信息成功:{}", userAccountSid, JSON.toJSONString(baseUserInfoDo));
            return baseUserInfoDo;
        } catch (Exception e) {
            log.error("根据userAccountSid:{}获取用户信息失败:{}", userAccountSid, JSON.toJSONString(e));
            return null;
        }
    }

    /* 查询车辆银基蓝牙钥匙 */
    private BaseRestResponse<VinBluetoothsVo> getIneekByVin(VinBluetoothsVo vinBluetoothsVo, String vin) {
        BaseRestResponse<VinBluetoothsVo> response = null;
        List<IngeekBluetoothDataDo> ingeekList = null;
        BluetoothVo bluetoothVo = new BluetoothVo();

        try {
            ingeekList = msDeviceMapper.getBluetoothDataByVin(vin);
            log.info("根据vin:{}查询银基蓝牙钥匙完成：{}", vin, JSON.toJSONString(ingeekList));
        } catch(Exception e) {
            ingeekList = null;
            log.error("根据vin:{}查询银基蓝牙钥匙失败:{}", vin, JSON.toJSONString(e));
            response = new BaseRestResponse<>("-1","查询车辆:" + vin + "银基蓝牙钥匙失败", null);
            return response;
        }

        if (ingeekList != null && ingeekList.size() > 0) {
            vinBluetoothsVo.setKeyType(BluetoothKeyTypeEnum.INGEEK.getValue());
            ingeekList.forEach(t -> {
                bluetoothVo.setId(t.getSid());
//                        .setStatus(t.getFreezeStatus().equals(0) ? "正常" : "失效")
//                        .setStartTime(DateUtils.dateToString(t.getActiveDate()))
//                        .setEndTime(t.getValidDay());
                vinBluetoothsVo.getBluetooths().add(bluetoothVo);
            });
            ingeekList = null;
            response = new BaseRestResponse<>("200","获取车辆:" + vin + "蓝牙钥匙信息成功", vinBluetoothsVo);
            return response;
        }

        return null;
    }

    /* 查询车辆博泰蓝牙钥匙 */
    private BaseRestResponse<VinBluetoothsVo> getPateoByVin(VinBluetoothsVo vinBluetoothsVo, String vin) {
        BaseRestResponse<VinBluetoothsVo> response = null;
        List<BluetoothUserKeyDo> pateoList = null;
        try {
            pateoList = msBluetoothMapper.getBluetoothByVinFromPateo(vin);
            log.info("根据vin:{}查询车辆传统蓝牙钥匙完成:{}", vin, JSON.toJSONString(pateoList));

            if(pateoList != null && pateoList.size() > 0) {
                vinBluetoothsVo.setKeyType(BluetoothKeyTypeEnum.PATEO.getValue());
                pateoList.forEach(t -> {
                    log.info("查询蓝牙钥匙:{}绑定用户:{}信息",t.getId(),t.getUserAccountSid());
                    BaseUserInfoDo baseUserInfoDo = getUserInfoByAccountSid(t.getUserAccountSid());
                    BluetoothVo bluetoothVo = new BluetoothVo()
                            .setRelationship(t.getRelationship().equals(1) ? "车主" : "非车主")
                            .setId(t.getId())
                            .setStartTime(DateUtils.dateToString(t.getKeyAssignTime()))
                            .setEndTime(DateUtils.dateToString(t.getKeyExpireTime()))
                            .setStatus(BluetoothKeyStatusEnum.getInfoByValue(t.getKeyStatus()))
                            .setKeyDestroyTime(DateUtils.dateToString(t.getKeyDestroyTime()))
                            .setKeyRefreshTime(DateUtils.dateToString(t.getKeyRefreshTime()))
                            .setUserAccountSid(t.getUserAccountSid())
                            .setUserAccountId(baseUserInfoDo == null ? null : baseUserInfoDo.getAccountId())
                            .setMobilePhone(baseUserInfoDo == null ? null : baseUserInfoDo.getMobilePhone())
                            .setThirdType(baseUserInfoDo == null ? null : baseUserInfoDo.getThirdType())
                            .setThirdUid(baseUserInfoDo == null ? null : baseUserInfoDo.getThirdUid());

                    vinBluetoothsVo.getBluetooths().add(bluetoothVo);
                });

                response = new BaseRestResponse<>("200","获取车辆:" + vin + "蓝牙钥匙信息成功", vinBluetoothsVo);
                return response;
            }
            return null;
        } catch(Exception e) {
            pateoList = null;
            log.error("查询车辆:{}传统蓝牙钥匙失败，异常信息:{}", vin, JSON.toJSONString(e));
            response = new BaseRestResponse<>("-1","查询车辆:" + vin + "传统蓝牙钥匙失败", null);
            return response;
        }
    }

    /* 查询自研蓝牙钥匙 */
    private BaseRestResponse<VinBluetoothsVo> getDongfengByVin(VinBluetoothsVo vinBluetoothsVo, String vin) {
        BaseRestResponse<VinBluetoothsVo> response = null;
        List<BluetoothUserKeyDo> dongfengList = null;

        try {
            dongfengList = msBluetoothMapper.getBluetoothByVinFromDongfeng(vin);
            log.info("根据vin:{}查询车辆东风蓝牙钥匙完成:{}", vin, JSON.toJSONString(dongfengList));

            if(dongfengList != null && dongfengList.size() > 0) {
                vinBluetoothsVo.setKeyType(BluetoothKeyTypeEnum.PATEO.getValue());
                dongfengList.forEach(t -> {
                    log.info("查询蓝牙钥匙:{}绑定用户:{}信息",t.getId(),t.getUserAccountSid());
                    BaseUserInfoDo baseUserInfoDo = getUserInfoByAccountSid(t.getUserAccountSid());
                    BluetoothVo bluetoothVo = new BluetoothVo()
                            .setRelationship(t.getRelationship().equals(1) ? "车主" : "非车主")
                            .setId(t.getId())
                            .setStartTime(DateUtils.dateToString(t.getKeyAssignTime()))
                            .setEndTime(DateUtils.dateToString(t.getKeyExpireTime()))
                            .setStatus(BluetoothKeyStatusEnum.getInfoByValue(t.getKeyStatus()))
                            .setKeyDestroyTime(DateUtils.dateToString(t.getKeyDestroyTime()))
                            .setKeyRefreshTime(DateUtils.dateToString(t.getKeyRefreshTime()))
                            .setUserAccountSid(t.getUserAccountSid())
                            .setUserAccountId(baseUserInfoDo == null ? null : baseUserInfoDo.getAccountId())
                            .setMobilePhone(baseUserInfoDo == null ? null : baseUserInfoDo.getMobilePhone())
                            .setThirdType(baseUserInfoDo == null ? null : baseUserInfoDo.getThirdType())
                            .setThirdUid(baseUserInfoDo == null ? null : baseUserInfoDo.getThirdUid());

                    vinBluetoothsVo.getBluetooths().add(bluetoothVo);
                });

                response = new BaseRestResponse<>("200","获取车辆:" + vin + "蓝牙钥匙信息成功", vinBluetoothsVo);
                return response;
            }
            return null;
        } catch(Exception e) {
            dongfengList = null;
            log.error("查询车辆:{}东风蓝牙钥匙失败，异常信息:{}", vin, JSON.toJSONString(e));
            response = new BaseRestResponse<>("-1","查询车辆:" + vin + "东风蓝牙钥匙失败", null);
            return response;
        }
    }
}
